
#include "mpi_lib.h"
#include "mpi_vdec.h"
#include "mpi.h"


int sgks_mpi_vdec_MmapPhyAddr(sgks_mpi_vdec_init_Param_s *vdec_param)
{

    CHECK_POINT_NULL_RETURN(vdec_param, SGKS_FAIL);

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_mmap_s *mmap_info = msg_buf;

    SGKS_MDI_DRV_CLEAN_DATABUFF();
    mmap_info->mmap_phy_start_addr = (char *)vdec_param->vdec_buff.buff_ptr_phy;
    mmap_info->mmap_phy_size       = (int)vdec_param->vdec_buff.size;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_MMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    vdec_param->vdec_buff.buff_ptr_vir = (u32 *)mmap_info->mmap_user_start_addr;
    Printf("vdec map: phy addr 0x%x ----> vir 0x%x    size 0x%x\n",vdec_param->vdec_buff.buff_ptr_phy, mmap_info->mmap_user_start_addr, mmap_info->mmap_user_size);

    return SGKS_SUCCESS;

}

int sgks_mpi_vdec_SendStopDecFlag(sgks_mpi_manager_s *mpi)
{

    CHECK_POINT_NULL_RETURN(mpi, SGKS_FAIL);
    unsigned char eos[] = {0x00, 0x00, 0x00, 0x01, 0x0A};
    int ret = -1;

    if (mpi->vdec_manager.decing_flags == DECODE_H264)
    {

        ret = sgks_mpi_vdec_SendData(eos, sizeof(eos));

        if (ret < 0)
        {
            Printf("sgks_mpi_vdec_SendStopDecFlag failed! ret=%d\n", ret);
            return SGKS_ERR_VDEC_STOPDECSENDFLAGERR;
        }

        Printf("sgks_mpi_vdec_SendStopDecFlag h264 ok!\n");

    }

    Printf("sgks_mpi_vdec_SendStopDecFlag ok!\n");

    return SGKS_SUCCESS;

}


int sgks_mpi_vdec_UnMmapPhyAddr(sgks_mpi_vdec_init_Param_s *vdec_param)
{

    CHECK_POINT_NULL_RETURN(vdec_param, SGKS_FAIL);

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_mmap_s *mmap_info = msg_buf;

    SGKS_MDI_DRV_CLEAN_DATABUFF();

    mmap_info->mmap_user_start_addr = vdec_param->vdec_buff.buff_ptr_vir;
    mmap_info->mmap_user_size       = vdec_param->vdec_buff.size;

    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_UNMMAP, 0, sizeof(sgks_mdi_mmap_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    Printf("vdec unmap: ok\n");

    return SGKS_SUCCESS;

}



int sgks_mpi_vdec_Cmd_Config(sgks_mpi_manager_s *mpi)
{
    u32 i;
    int ret  = -1;

    sgks_dsp_cmd_rescale_s dsp_cmd;
    sgks_mpi_vdec_init_Param_s *vdec_init = &mpi->vdec_init_param;

    memset(&dsp_cmd, 0, sizeof(sgks_dsp_cmd_rescale_s));

    //is_media_state_decoding() || G_media_obj.decode_state != DECODE_STOPPED)


    dsp_cmd.cmd_code = SGKS_DSP_CMD_DECODE_RESCALE;

    if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_MJPEG)
    {
        dsp_cmd.rescale_total_num = vdec_init->rescale_sub_num;

        for(i = 0; i < MAX_VDEC_RESCALE_SUB_NUM; i++)
        {
            dsp_cmd.rescale_width[i]  = vdec_init->rescale_sub[i].width;
            dsp_cmd.rescale_height[i] = vdec_init->rescale_sub[i].height;
        }
    }

    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd(dsp_cmd, rescale_total_num);
    mpi_cmd_hex(dsp_cmd, rescale_width[0]);
    mpi_cmd_hex(dsp_cmd, rescale_height[0]);
    mpi_cmd_hex(dsp_cmd, rescale_width[1]);
    mpi_cmd_hex(dsp_cmd, rescale_height[1]);
    mpi_cmd_hex(dsp_cmd, rescale_width[2]);
    mpi_cmd_hex(dsp_cmd, rescale_height[2]);
    mpi_cmd_hex(dsp_cmd, rescale_width[3]);
    mpi_cmd_hex(dsp_cmd, rescale_height[3]);
    mpi_cmd_hex(dsp_cmd, rescale_width[4]);
    mpi_cmd_hex(dsp_cmd, rescale_height[4]);

    ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_rescale_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }


    return SGKS_SUCCESS;


}




int sgks_mpi_vdec_Enable(sgks_mpi_vdec_init_Param_s *vdec_param)
{

    CHECK_POINT_NULL_RETURN(vdec_param, SGKS_FAIL);
    CHECK_POINT_NULL_RETURN(vdec_param->vdec_buff.buff_ptr_phy, SGKS_FAIL);
    int ret = -1;


    sgks_mpi_manager_s *mpi = mpi_get_managerHanle();
    if (mpi->vdec_manager.decing_flags != DECODE_STOPPED)
    {
        Printf(" VDEC REPEAT ENABLE\n");
        return SGKS_ERR_VDEC_REPEAT_ENABLE;
    }



    if(vdec_param->file_info.width <= 0 || vdec_param->file_info.width > MAX_VDEC_WIDTH
            || vdec_param->file_info.height <= 0 || vdec_param->file_info.height > MAX_VDEC_HEIGHT)
    {
        Printf("vdec width or height err\n");
        return SGKS_ERR_VDEC_INITPARAMERR;
    }

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_GETPAGESIZE, 0, sizeof(sgks_get_pagesize_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    sgks_get_pagesize_s *kernel_page = msg_buf;
    u32 page_size = kernel_page->page_size;

    SGKS_MPI_CHECK_MEM_PAGE_ALIGN((u32)vdec_param->vdec_buff.buff_ptr_phy, 	page_size, SGKS_ERR_SYS_INITMEMPARAMFAIL);

    sgks_mpi_vdec_MmapPhyAddr(vdec_param);

    memcpy(&mpi->vdec_init_param, vdec_param, sizeof(sgks_mpi_vdec_init_Param_s));

    memset(mpi->vdec_init_param.vdec_buff.buff_ptr_vir, 0, mpi->vdec_init_param.vdec_buff.size);

    memset(&mpi->vdec_manager, 0, sizeof(sgks_mpi_vdec_manager_s));

    mpi->vdec_manager.buff_start		= mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
    mpi->vdec_manager.buff_end			= mpi->vdec_init_param.vdec_buff.buff_ptr_vir;

    SGKS_MDI_DRV_CLEAN_DATABUFF();
    sgks_mdi_vdec_buff_s *vdec_buff 	= msg_buf;
    vdec_buff->buff_phy					= vdec_param->vdec_buff.buff_ptr_phy;
    vdec_buff->buff_size				= vdec_param->vdec_buff.size;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_SET_VDEC_BUFF_INFO, 0, sizeof(sgks_mdi_vdec_buff_s), SGKS_ERR_SYS_DRIVERIOCTLERR);


    //enc to dec
    ret = sgks_mpi_sys_EncToDec();
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    //update vo
    sgks_mpi_cmd_SetMode(mpi, SGKS_MDI_CMD_MODE_BLOCK_LOADING);
	
	if (mpi->cap_init_param.cap_type == SGKS_CAP_YUV_SOURCE_TYPE_VDEC_RAW)
	{
		mpi->mpi_vo_dev[0].video_setup.src = SGKS_VO_SRC_YUV422;
	}
	else
	{
		mpi->mpi_vo_dev[0].video_setup.src = SGKS_VO_SRC_DEC;
	}
	
    sgks_mpi_vo_Cmd(mpi,SGKS_VIDEO_VOUT_SW);
    sgks_mpi_cmd_SetMode(mpi, SGKS_MDI_CMD_MODE_BLOCK_READY);

    //vdec config
    sgks_mpi_cmd_SetMode(mpi, SGKS_MDI_CMD_MODE_NORMAL_LOADING);
    ret = sgks_mpi_vdec_Cmd_Config(mpi);
    if (ret != SGKS_SUCCESS)
        return ret;
	sgks_mpi_cmd_SetMode(mpi, SGKS_MDI_CMD_MODE_NORMAL_READY);

    //ResetVout


    sgks_mpi_cmd_SetMode(mpi, SGKS_MDI_CMD_MODE_VDEC_NORMAL_LOADING);

    return SGKS_SUCCESS;

}


int sgks_mpi_vdec_PlayControl(sgks_mpi_vdec_PlayControl_s *PlayControl)
{



    return SGKS_SUCCESS;
}


inline int sgks_mpi_vdec_WriteBuff(sgks_mpi_manager_s *mpi, u8 *data, u32 size)
{

    u8 *curr_write_pos				= mpi->vdec_manager.buff_end;
    u8 *buff_start_addr 			= mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
    u32 buff_size 					= mpi->vdec_init_param.vdec_buff.size;
    u32 nSize 						= 0;

    //Printf("curr_write_pos 0x%x, %d\n",curr_write_pos,size);

    if((curr_write_pos + size) > (buff_start_addr + buff_size))
    {

        //Printf("start begin\n");

        if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_H264)
        {
            nSize = buff_start_addr + buff_size - curr_write_pos;
            memcpy(curr_write_pos, data, nSize);

            curr_write_pos = buff_start_addr;
            memcpy(curr_write_pos, data + nSize, size - nSize);
            curr_write_pos += (size - nSize);
        }
        else if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_MJPEG)
        {
            memcpy(buff_start_addr, data, size);
            mpi->vdec_manager.buff_end		= buff_start_addr;
            curr_write_pos 					= buff_start_addr + size;
        }

    }
    else
    {

        //Printf("next\n");
        memcpy(curr_write_pos, data, size);
        curr_write_pos += size;

    }


    mpi->vdec_manager.buff_start	= mpi->vdec_manager.buff_end;
    mpi->vdec_manager.buff_end 		= curr_write_pos;

    //Printf("=== mpi->vdec_manager.buff_start 0x%x,mpi->vdec_manager.buff_end 0x%x\n",mpi->vdec_manager.buff_start,mpi->vdec_manager.buff_end);

    return SGKS_SUCCESS;

}


inline int sgks_mpi_vdec_QueryDspRoom(sgks_mpi_manager_s *mpi, u32 data_size)
{
    CHECK_POINT_NULL_RETURN(mpi, SGKS_FAIL);


    if (mpi->vdec_init_param.file_info.type != SGKS_VDEC_TYPE_H264)
    {
        return SGKS_SUCCESS;
    }

    u8 *msg_buf = NULL;
    u32 room  = 0;
    u8 *buff_startaddr 		= mpi->vdec_manager.buff_end;  /*write*/
    u32 buff_size 				= mpi->vdec_init_param.vdec_buff.size;
    u8 *dsp_readpos			= NULL;/*read*/



    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_vdec_buff_pos_s *dsp_vdec_buff = msg_buf;

    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_GET_VDEC_BUFF_POS, 0, sizeof(sgks_mdi_vdec_buff_pos_s), SGKS_ERR_VDEC_DSPBUFFROOM_ERR);



    u32 pos = dsp_vdec_buff->curr_pos;



    dsp_readpos = mpi->vdec_init_param.vdec_buff.buff_ptr_vir + pos;

    //Printf("dsp_readpos 0x%x buff_startaddr 0x%x pos %d\n", dsp_readpos , buff_startaddr , pos);

    if(dsp_readpos > buff_startaddr)
    {
        //Printf("dsp_readpos > buff_startaddr\n");
        room = dsp_readpos - buff_startaddr;
    }
    else
    {
        //Printf("dsp_readpos < buff_startaddr\n");
        room = buff_size - (buff_startaddr - dsp_readpos);
    }

    //Printf("room == %d\n",room);

    if(room >= data_size + 1024)
    {
        //Printf("DSP BUFF ROOM ENOUGH\n");
        return SGKS_SUCCESS;
    }
    else
    {
        //Printf("DSP BUFF ROOM NOT ENOUGH\n");
        return SGKS_ERR_VDEC_DSPBUFFROOM_NOT_ENOUGH;
    }

    return SGKS_SUCCESS;

}




inline int sgks_mpi_vdec_Cmd_DecodeMjpegUpdate(sgks_mpi_manager_s *mpi)
{

    u32 addr;
    sgks_dsp_cmd_jpeg_decode_s dsp_cmd;
    memset(&dsp_cmd, 0, sizeof(dsp_cmd));

    dsp_cmd.cmd_code 				= SGKS_DSP_CMD_JPEG_DECODE;
    dsp_cmd.bits_fifo_start 		= mpi->vdec_manager.vdec_mjpeg_info.addr;
    dsp_cmd.bits_fifo_end 			= mpi->vdec_manager.vdec_mjpeg_info.addr + mpi->vdec_manager.vdec_mjpeg_info.size;
    dsp_cmd.main_rotation 			= 0;
    dsp_cmd.ycbcr_position 			= 0;
    dsp_cmd.frame_duration 			= 0;
    dsp_cmd.num_frame_decode 		= 1;
    dsp_cmd.already_decoded 		= 0;

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_opt_d_cache_s *cache 	 = msg_buf;


    cache->cache_type                = SGKS_OPT_D_CACHE_CLAEN;
    cache->start                     = mpi->vdec_manager.buff_start;
    cache->size                      = mpi->vdec_manager.buff_end - mpi->vdec_manager.buff_start;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);


    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd_hex(dsp_cmd, bits_fifo_start);
    mpi_cmd_hex(dsp_cmd, bits_fifo_end);
    mpi_cmd(dsp_cmd, main_rotation);
    mpi_cmd(dsp_cmd, ycbcr_position);
    mpi_cmd(dsp_cmd, frame_duration);
    mpi_cmd(dsp_cmd, num_frame_decode);
    mpi_cmd(dsp_cmd, already_decoded);

    int ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_jpeg_decode_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;

}



inline int sgks_mpi_vdec_Cmd_DecodeH264Update(sgks_mpi_manager_s *mpi)
{
    u32 start_addr;
    u32 end_addr;
    sgks_dsp_cmd_h264_decode_bits_fifo_update_s dsp_cmd;
    memset(&dsp_cmd, 0, sizeof(dsp_cmd));

    dsp_cmd.cmd_code 			= SGKS_DSP_CMD_H264_DECODE_BITS_FIFO_UPDATE;
    dsp_cmd.bits_fifo_start 	= mpi->vdec_manager.vdec_info.start_addr;
    dsp_cmd.bits_fifo_end    	= mpi->vdec_manager.vdec_info.end_addr	- 1;
    dsp_cmd.num_pics 			= mpi->vdec_manager.vdec_info.num_pics;

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_opt_d_cache_s *cache 	 = msg_buf;

    if (mpi->vdec_manager.buff_end >  mpi->vdec_manager.buff_start)
    {

        cache->cache_type                = SGKS_OPT_D_CACHE_CLAEN;
        cache->start                     = mpi->vdec_manager.buff_start;
        cache->size                      = mpi->vdec_manager.buff_end - mpi->vdec_manager.buff_start;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);
    }
    else if (mpi->vdec_manager.buff_end <  mpi->vdec_manager.buff_start)
    {

        cache->cache_type                = SGKS_OPT_D_CACHE_CLAEN;
        cache->start                     = mpi->vdec_manager.buff_start;
        cache->size                      = (mpi->vdec_init_param.vdec_buff.buff_ptr_vir + mpi->vdec_init_param.vdec_buff.size) - mpi->vdec_manager.buff_start;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

        cache->cache_type                = SGKS_OPT_D_CACHE_CLAEN;
        cache->start                     = mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
        cache->size                      = mpi->vdec_manager.buff_end - mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
        SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);

    }

    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd_hex(dsp_cmd, bits_fifo_start);
    mpi_cmd_hex(dsp_cmd, bits_fifo_end);
    mpi_cmd(dsp_cmd, num_pics);

    int ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_h264_decode_bits_fifo_update_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    //sgks_dsp_decode_bits_update(&dsp_cmd);

    return SGKS_SUCCESS;

}
inline int sgks_mpi_vdec_Cmd_DecodeH264(sgks_mpi_manager_s *mpi)
{
    int ret = -1;
    u32 start_addr;
    u32 end_addr;
    sgks_dsp_cmd_h264_decode_s dsp_cmd;
    memset(&dsp_cmd, 0, sizeof(dsp_cmd));

    dsp_cmd.cmd_code 			= SGKS_DSP_CMD_H264_DECODE;
    dsp_cmd.bits_fifo_start 	= mpi->vdec_manager.vdec_info.start_addr;
    dsp_cmd.bits_fifo_end 		= mpi->vdec_manager.vdec_info.end_addr - 1;
    dsp_cmd.num_pics 			= mpi->vdec_manager.vdec_info.num_pics;
    dsp_cmd.num_frame_decode 	= 0;
    dsp_cmd.first_frame_display = mpi->vdec_manager.vdec_info.first_display_pts;
    dsp_cmd.fade_in_on 			= 0;
    dsp_cmd.fade_out_on 		= 0;


    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_opt_d_cache_s *cache 	 = msg_buf;
    cache->cache_type                = SGKS_OPT_D_CACHE_CLAEN;
    cache->start                     = mpi->vdec_manager.buff_start;
    cache->size                      = mpi->vdec_manager.buff_end - mpi->vdec_manager.buff_start;
    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_OPT_D_CACHE, 0, sizeof(sgks_mdi_opt_d_cache_s), SGKS_ERR_SYS_DRIVERIOCTLERR);


    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd_hex(dsp_cmd, bits_fifo_start);
    mpi_cmd_hex(dsp_cmd, bits_fifo_end);
    mpi_cmd(dsp_cmd, num_pics);
    mpi_cmd(dsp_cmd, num_frame_decode);
    mpi_cmd(dsp_cmd, first_frame_display);
    mpi_cmd(dsp_cmd, fade_in_on);
    mpi_cmd(dsp_cmd, fade_out_on);

    ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_h264_decode_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;

}



inline int sgks_mpi_vdec_Cmd_RescalePostProc(sgks_mpi_manager_s *mpi)
{

    int ret = -1;

    sgks_dsp_cmd_rescale_postproc_s dsp_cmd;

    memset(&dsp_cmd, 0, sizeof(dsp_cmd));

    dsp_cmd.cmd_code 				= SGKS_DSP_CMD_RESCALE_POSTPROCESSING;
    dsp_cmd.input_center_x 			= mpi->vdec_init_param.file_info.width  / 2;
    dsp_cmd.input_center_y 			= mpi->vdec_init_param.file_info.height / 2;
    dsp_cmd.display_win_offset_x 	= 0;
    dsp_cmd.display_win_offset_y 	= 0;

    if (mpi->mpi_vo_dev[SGKS_VOUT_B].vo_user_param.vo_src == SGKS_VO_SRC_DEC)
    {
        dsp_cmd.display_win_width 		= mpi->mpi_vo_dev[SGKS_VOUT_B].vo_user_param.video_info.width;
        dsp_cmd.display_win_height 		= mpi->mpi_vo_dev[SGKS_VOUT_B].vo_user_param.video_info.height;
    }

    dsp_cmd.zoom_factor_x 			= 1;    // center, scale to video output, preserving aspect ratio
    dsp_cmd.zoom_factor_y 			= 1;    // center, scale to video output, preserving aspect ratio
    dsp_cmd.apply_yuv 				= 1;

    if (mpi->mpi_vo_dev[SGKS_VOUT_A].vo_user_param.vo_src == SGKS_VO_SRC_DEC)
    {
        dsp_cmd.sec_display_win_width 	= mpi->mpi_vo_dev[SGKS_VOUT_A].vo_user_param.video_info.width;
        dsp_cmd.sec_display_win_height 	= mpi->mpi_vo_dev[SGKS_VOUT_A].vo_user_param.video_info.height;
    }

    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd(dsp_cmd, input_center_x);
    mpi_cmd(dsp_cmd, input_center_y);
    mpi_cmd(dsp_cmd, display_win_offset_x);
    mpi_cmd(dsp_cmd, display_win_offset_y);
    mpi_cmd(dsp_cmd, display_win_width);
    mpi_cmd(dsp_cmd, display_win_height);
    mpi_cmd(dsp_cmd, zoom_factor_x);
    mpi_cmd(dsp_cmd, zoom_factor_y);
    mpi_cmd(dsp_cmd, apply_yuv);

    ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_rescale_postproc_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;


}


inline int sgks_mpi_vdec_Cmd_SetupRgbToYuv(sgks_mpi_manager_s *mpi)
{
    sgks_dsp_cmd_rgb_to_yuv_setup_s dsp_cmd;

    memset(&dsp_cmd, 0, sizeof(dsp_cmd));

    dsp_cmd.cmd_code 				= SGKS_DSP_CMD_RGB_TO_YUV_SETUP;
    dsp_cmd.matrix_values[0] 		= 0x370;
    dsp_cmd.matrix_values[1] 		= 0;
    dsp_cmd.matrix_values[2] 		= 0;
    dsp_cmd.matrix_values[3] 		= 0;
    dsp_cmd.matrix_values[4] 		= 0x400;
    dsp_cmd.matrix_values[5] 		= 0;
    dsp_cmd.matrix_values[6] 		= 0;
    dsp_cmd.matrix_values[7] 		= 0;
    dsp_cmd.matrix_values[8] 		= 0x400;
    dsp_cmd.y_offset 				= 0x10;
    dsp_cmd.u_offset 				= 0x80;
    dsp_cmd.v_offset 				= 0x80;

    mpi_cmd_hex(dsp_cmd, cmd_code);

    int ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_rgb_to_yuv_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;

}


inline int sgks_mpi_vdec_Cmd_SetupJpegInfo(sgks_mpi_manager_s *mpi)
{
    int ret = -1;

    sgks_dsp_cmd_jpeg_decode_setup_s dsp_cmd;
    memset(&dsp_cmd, 0, sizeof(dsp_cmd));
    dsp_cmd.cmd_code 					= SGKS_DSP_CMD_JPEG_DECODING_SETUP;
    dsp_cmd.bits_fifo_base 				= mpi->vdec_init_param.vdec_buff.buff_ptr_phy;
    dsp_cmd.bits_fifo_limit 			= (u32)((u8*)mpi->vdec_init_param.vdec_buff.buff_ptr_phy + mpi->vdec_init_param.vdec_buff.size - 1);

    dsp_cmd.background_y 				= 0x10;
    dsp_cmd.background_cb 				= 0x80;
    dsp_cmd.background_cr 				= 0x80;

    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd_hex(dsp_cmd, bits_fifo_base);
    mpi_cmd_hex(dsp_cmd, bits_fifo_limit);

    ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_jpeg_decode_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;

}


inline int sgks_mpi_vdec_Cmd_SetupH264Info(sgks_mpi_manager_s *mpi)
{
    int ret = -1;

    sgks_dsp_cmd_h264_decode_setup_s dsp_cmd;

    memset(&dsp_cmd, 0, sizeof(dsp_cmd));


    dsp_cmd.cmd_code 				= SGKS_DSP_CMD_H264_DECODING_SETUP;
    dsp_cmd.bits_fifo_base 			= mpi->vdec_init_param.vdec_buff.buff_ptr_phy;
    dsp_cmd.bits_fifo_limit 		= (u32)((u8*)mpi->vdec_init_param.vdec_buff.buff_ptr_phy + mpi->vdec_init_param.vdec_buff.size - 1);

    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd_hex(dsp_cmd, bits_fifo_base);
    mpi_cmd_hex(dsp_cmd, bits_fifo_limit);

    ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_h264_decode_setup_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    return SGKS_SUCCESS;

}

//flag 0:stop dec ,clear screen 1:stop dec, not clear screen
inline int sgks_mpi_vdec_Cmd_StopDec(sgks_mpi_manager_s *mpi, u32 flag)
{
    int  ret = -1;

    if (mpi->vdec_manager.decing_flags == DECODE_STOPPED)
    {
        Printf("Already DECODE_STOPPED\n");
        return SGKS_FAIL;
    }

    sgks_dsp_cmd_h264_decode_stop_s dsp_cmd;
    memset(&dsp_cmd, 0, sizeof(dsp_cmd));
    dsp_cmd.cmd_code 		= SGKS_DSP_CMD_DECODE_STOP;
    dsp_cmd.stop_flag 		= flag;


    mpi_cmd_hex(dsp_cmd, cmd_code);
    mpi_cmd(dsp_cmd, stop_flag);


    ret = sgks_mpi_cmd_Send(&dsp_cmd, sizeof(sgks_dsp_cmd_h264_decode_stop_s));
    if (ret != SGKS_SUCCESS)
    {
        return ret;
    }

    sgks_mdi_dsp_status_s dsp_status;
    dsp_status.op_mode  = SGKS_DSP_DECODE_MODE;
    dsp_status.op_sub_mode  = -1;

    if (flag == 1)
        dsp_status.state	= SGKS_DEC_H264DEC_IDLE_STATE;
    else
        dsp_status.state	= SGKS_DEC_IDLE_STATE;

    ret = sgks_mpi_sys_WaitDspStats(&dsp_status);
    if (ret != SGKS_SUCCESS)
        return ret;

    mpi->vdec_manager.decing_flags = DECODE_STOPPED;

    return SGKS_SUCCESS;

}

inline int sgks_mpi_vdec_SendH264DataToDsp(sgks_mpi_manager_s *mpi)
{

#if 0
    sgks_mpi_vdec_FeedH264Info_t h264_item;

    h264_item.startAddr 		= mpi->vdec_manager.buff_start;
    h264_item.endAddr 			= mpi->vdec_manager.buff_end;
    h264_item.firstPTS 			= 0;
    h264_item.nextSize 			= 0;
    h264_item.picHeight 		= 0;
    h264_item.picWidth 			= 0;
    h264_item.picNums 			= 1;
#endif
    sgks_mdi_dsp_status_s dsp_status;

    sgks_h264_decode_t info;
    memset(&info, 0, sizeof(sgks_h264_decode_t));

    u32 buff_vir_start_pos		= mpi->vdec_manager.buff_start - mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
    u8 *buff_phy_start_ptr 	    = (u8*)mpi->vdec_init_param.vdec_buff.buff_ptr_phy + buff_vir_start_pos;

    u32 buff_vir_end_pos			= mpi->vdec_manager.buff_end - mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
    u8 *buff_phy_end_ptr	 	    = (u8*)mpi->vdec_init_param.vdec_buff.buff_ptr_phy + buff_vir_end_pos;

    //Printf("[h264] buff_phy_start_ptr 0x%x, buff_phy_end_ptr 0x%x\n",buff_phy_start_ptr,buff_phy_end_ptr);

    info.start_addr 				= buff_phy_start_ptr;
    info.end_addr   				= buff_phy_end_ptr;
    info.num_pics   				= 1;
    info.next_size  				= 0;
    info.pic_width  				= 0;
    info.pic_height 				= 0;
    info.pts        				= 0;
    info.pts_high   				= 0;
    info.first_display_pts 			= 0;

    memcpy(&mpi->vdec_manager.vdec_info, &info, sizeof(sgks_h264_decode_t));

    //is_media_state_decoding


    //stop dec
    if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_H264)
    {
        if (mpi->vdec_manager.decing_flags != DECODE_H264)
        {
            sgks_mpi_vdec_Cmd_StopDec(mpi, 0);
            sgks_mpi_vdec_Cmd_SetupH264Info(mpi);
            sgks_mpi_vdec_Cmd_RescalePostProc(mpi);
            sgks_mpi_vdec_Cmd_DecodeH264(mpi);

            memset(&dsp_status, 0, sizeof(sgks_mdi_dsp_status_s));
            dsp_status.op_mode  	= SGKS_DSP_DECODE_MODE;
            dsp_status.op_sub_mode	= -1;
            dsp_status.state		= SGKS_DEC_H264DEC_STATE;
            int ret = sgks_mpi_sys_WaitDspStats(&dsp_status);
            if (ret != SGKS_SUCCESS)
                return ret;

            mpi->vdec_manager.decing_flags = DECODE_H264;

        }
        else
        {
            sgks_mpi_vdec_Cmd_DecodeH264Update(mpi);
        }

    }

    return SGKS_SUCCESS;



}




inline int sgks_mpi_vdec_SendMjpegDataToDsp(sgks_mpi_manager_s *mpi)
{

    sgks_mdi_dsp_status_s dsp_status;

    sgks_mjpeg_decode_t info;
    memset(&info, 0, sizeof(sgks_mjpeg_decode_t));

    u32 buff_vir_start_pos		= mpi->vdec_manager.buff_start - mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
    u8 *buff_phy_start_ptr 	    = (u8*)mpi->vdec_init_param.vdec_buff.buff_ptr_phy + buff_vir_start_pos;

    u32 buff_vir_end_pos			= mpi->vdec_manager.buff_end - mpi->vdec_init_param.vdec_buff.buff_ptr_vir;
    u8 *buff_phy_end_ptr	 	    = (u8*)mpi->vdec_init_param.vdec_buff.buff_ptr_phy + buff_vir_end_pos;

    //Printf("[Mjpeg] buff_phy_start_ptr 0x%x, buff_phy_end_ptr 0x%x size %d\n",buff_phy_start_ptr,buff_phy_end_ptr,buff_phy_end_ptr - buff_phy_start_ptr);

    info.addr						= buff_phy_start_ptr;
    info.size						= buff_phy_end_ptr - buff_phy_start_ptr;


    memcpy(&mpi->vdec_manager.vdec_mjpeg_info, &info, sizeof(sgks_mjpeg_decode_t));

    //is_media_state_decoding


    //stop dec
    if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_MJPEG)
    {
        if (mpi->vdec_manager.decing_flags != DECODE_JPEG)
        {
            sgks_mpi_vdec_Cmd_StopDec(mpi, 0);
            sgks_mpi_vdec_Cmd_SetupRgbToYuv(mpi);
            sgks_mpi_vdec_Cmd_SetupJpegInfo(mpi);
            sgks_mpi_vdec_Cmd_RescalePostProc(mpi);

            mpi->vdec_manager.decing_flags = DECODE_JPEG;

        }

        sgks_mpi_vdec_Cmd_DecodeMjpegUpdate(mpi);

        memset(&dsp_status, 0, sizeof(sgks_mdi_dsp_status_s));
        dsp_status.op_mode  	= SGKS_DSP_DECODE_MODE;
        dsp_status.op_sub_mode	= -1;
        dsp_status.state		= SGKS_DEC_JPEGSTILL_STATE;
        int ret = sgks_mpi_sys_WaitDspStats(&dsp_status);
        if (ret != SGKS_SUCCESS)
            return ret;

    }

    return SGKS_SUCCESS;



}



int sgks_mpi_vdec_SendData(u8 *data, int size)
{
    CHECK_POINT_NULL_RETURN(data, SGKS_FAIL);

    int ret = 1;
    u32 cur_frame_start_ptr;
    u32 cur_frame_end_ptr;

    if (size <= 0)
    {
        return SGKS_FAIL;
    }

    sgks_mpi_manager_s *mpi = mpi_get_managerHanle();


    ret = sgks_mpi_vdec_QueryDspRoom(mpi, size);
    if (ret != SGKS_SUCCESS)
        return ret;


    ret = sgks_mpi_vdec_WriteBuff(mpi, data, size);
    if (ret != SGKS_SUCCESS)
        return ret;


    if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_H264)
    {
        ret = sgks_mpi_vdec_SendH264DataToDsp(mpi);
        if (ret != SGKS_SUCCESS)
            return ret;
    }
    else if (mpi->vdec_init_param.file_info.type == SGKS_VDEC_TYPE_MJPEG)
    {

        ret = sgks_mpi_vdec_SendMjpegDataToDsp(mpi);
        if (ret != SGKS_SUCCESS)
            return ret;

    }

    return SGKS_SUCCESS;


}


int sgks_mpi_vdec_GetDecInfo(sgks_mpi_vdec_info_s *dev_info)
{

    u8 *msg_buf = NULL;
    SGKS_MDI_DRV_BUFF(msg_buf);
    sgks_mdi_vdec_decode_info_s *dsp_vdec_info = msg_buf;

    SGKS_MDI_DRV_IOCTL(SGKS_MDI_OPERATION_GET_VDEC_INFO, 0, sizeof(sgks_mdi_vdec_decode_info_s), SGKS_ERR_VDEC_INFO_ERR);

    dev_info->curr_pts				= dsp_vdec_info->curr_pts;
    dev_info->curr_pts_high		= dsp_vdec_info->curr_pts_high;
    dev_info->decoded_frames		= dsp_vdec_info->decoded_frames;


    return SGKS_SUCCESS;

}


int sgks_mpi_vdec_UpdateParam(sgks_mpi_vdec_init_Param_s *vdec_param)
{



    return SGKS_SUCCESS;

}


int sgks_mpi_vdec_Disable(sgks_mpi_vdec_stop_Param_s *vdec_stop_Param)
{

    int ret = -1;
    sgks_mpi_manager_s *mpi = mpi_get_managerHanle();
    sgks_mdi_dsp_status_s dsp_status;

    if (mpi->vdec_manager.decing_flags == DECODE_STOPPED)
    {
        Printf("Already sgks_mpi_vdec_Disable\n");
        return SGKS_ERR_VDEC_STOPDECERR;
    }

    ret = sgks_mpi_vdec_SendStopDecFlag(mpi);
    if (ret != SGKS_SUCCESS)
        return ret;


    ret = sgks_mpi_vdec_Cmd_StopDec(mpi, vdec_stop_Param->screen);
    if (ret != SGKS_SUCCESS)
        return ret;

    ret = sgks_mpi_vdec_UnMmapPhyAddr(&mpi->vdec_init_param);
    if (ret != SGKS_SUCCESS)
        return ret;

    dsp_status.op_mode  	= -1;
    dsp_status.op_sub_mode	= -1;
    dsp_status.state    	= SGKS_DEC_IDLE_STATE;
    ret = sgks_mpi_sys_WaitDspStats(&dsp_status);
    if (ret != SGKS_SUCCESS)
        return ret;

    Printf("sgks_mpi_vdec_Disable ok\n");

    return SGKS_SUCCESS;

}










